<script setup lang="ts">
  import { useGetCustomFieldForCreate } from '@/services/pages/return-factory/useReturnFactory'
  import { ref } from 'vue'
  import { CustomForm } from '../types'
  import {
    FormInstance,
    UploadFile,
    ElForm,
    ElFormItem,
    ElSelect,
    ElOption,
    ElIcon,
    ElInput,
    ElUpload,
    ElRate,
    ElDatePicker,
  } from 'element-plus'
  import { HMessageBox } from '@/components/common/message'
  import infoTip from '@/config/info-tip'
  import pdf from '@/assets/image/pdf.png'
  import video from '@/assets/image/pages/order/new/video.png'
  import PdfPreview from './PdfPreview.vue'
  import VideoPreview from './VideoPreview.vue'
  import { UploadFilled } from '@element-plus/icons-vue'
  import moment from 'moment'

  const { loading, customFieldList, getCustomField } = useGetCustomFieldForCreate()

  defineOptions({
    name: 'CustomInfoReturnFactoryCreate',
  })

  // 表单组件实例
  const formInstance = ref<FormInstance | null>(null)

  // 表单列表
  const forms = ref<Array<CustomForm>>([])

  // 图片上传失败的提示次数
  const pictureUploadFailInfoTipCount = ref(0)

  // pdf上传失败的提示次数
  const pdfUploadFailInfoTipCount = ref(0)

  // 视频上传失败的提示次数
  const videoUploadFailInfoTipCount = ref(0)

  // pdf预览列表
  const pdfPreviewList = ref<Array<string>>([])

  // 当前正在预览的pdf的索引
  const currentPdfPreviewIndex = ref(0)

  // pdf预览弹窗显示状态
  const pdfPreviewDialogVisible = ref(false)

  // 视频预览列表
  const videoPreviewList = ref<Array<string>>([])

  // 当前正在预览的视频的索引
  const currentVideoPreviewIndex = ref(0)

  // 视频预览弹窗显示状态
  const videoPreviewDialogVisible = ref(false)

  /**
   * 自定义字段文件上传事件
   * @param {UploadFile} file - 文件对象
   * @param {Number} fieldIndex - 字段索引
   */
  const handleCustomFieldUploadFile = (file: UploadFile, fieldIndex: number) => {
    const field = forms.value[fieldIndex]
    const fileType = field.type === 5 ? 'image' : field.type === 6 ? 'pdf' : 'video'

    if (!file.raw.type.includes(fileType)) {
      const mdgOption = {
        image: infoTip.returnFactory.create.custom_field_picture_type_err,
        pdf: infoTip.returnFactory.create.custom_field_pdf_type_err,
        video: infoTip.returnFactory.create.custom_field_video_type_err,
      }
      HMessageBox.error(mdgOption[fileType])
      return
    }

    if (file.raw.size / 1024 / 1024 > field.uploadSize) {
      const mdgOption = {
        image: infoTip.returnFactory.create.custom_field_picture_size_err,
        pdf: infoTip.returnFactory.create.custom_field_pdf_size_err,
        video: infoTip.returnFactory.create.custom_field_video_size_err,
      }
      HMessageBox.error(mdgOption[fileType].replace('$size', `${field.uploadSize}`))
      return
    }

    if (forms.value[fieldIndex].fileList.length >= field.uploadQty) {
      const mdgOption = {
        image: infoTip.returnFactory.create.custom_field_picture_count_err,
        pdf: infoTip.returnFactory.create.custom_field_pdf_count_err,
        video: infoTip.returnFactory.create.custom_field_video_count_err,
      }
      HMessageBox.error(mdgOption[fileType].replace('$num', `${field.uploadQty}`))
      return
    }

    forms.value[fieldIndex].fileList.push({
      file: file.raw,
      url: URL.createObjectURL(file.raw),
    })
  }

  /**
   * pdf预览事件
   * @param {Number} formsIndex - 表单索引
   * @param {Number} pdfIndex - pdf索引
   */
  const handlePdfPreview = (formsIndex: number, pdfIndex: number) => {
    pdfPreviewList.value = forms.value[formsIndex].fileList.map((item) => item.url)
    currentPdfPreviewIndex.value = pdfIndex
    pdfPreviewDialogVisible.value = true
  }

  /**
   * 视频预览事件
   * @param {Number} formsIndex - 表单索引
   * @param {Number} videoIndex - pdf索引
   */
  const handleVideoPreview = (formsIndex: number, videoIndex: number) => {
    videoPreviewList.value = forms.value[formsIndex].fileList.map((item) => item.url)
    currentVideoPreviewIndex.value = videoIndex
    videoPreviewDialogVisible.value = true
  }

  /**
   * 文件上传校验方法
   * @param {Object} callback - 回调方法
   * @param {Number} formIndex - 表单索引
   */
  const fileUploadValidator = (callback: (err?: Error) => void, formIndex: number) => {
    if (forms.value[formIndex].required) {
      if (forms.value[formIndex].fileList.length === 0) {
        let tip = forms.value[formIndex].tip
        if (!tip) {
          switch (forms.value[formIndex].type) {
            case 5:
              tip = '请上传图片'
              break
            case 6:
              tip = '请上传附件'
              break
            case 7:
              tip = '请上传视频'
              break
          }
        }
        callback(new Error(forms.value[formIndex].tip || tip))
        return
      }

      callback()
      return
    }

    callback()
  }

  /**
   * 删除文件
   * @param {Number} formIndex - 表单索引
   * @param {Number} fileIndex - 文件索引
   */
  const handleDelFile = (formIndex: number, fileIndex: number) => {
    forms.value[formIndex].fileList.splice(fileIndex, 1)
  }

  /**
   * 日期更新事件
   * @param {Number} formIndex - 表单索引
   */
  const handleChangeDate = (formIndex: number) => {
    forms.value[formIndex].val = moment(forms.value[formIndex].val).format('YYYY-MM-DD')
  }

  /**
   * 日期时间更新事件
   * @param {Number} formIndex - 表单索引
   */
  const handleChangeDateTime = (formIndex: number) => {
    forms.value[formIndex].val = moment(forms.value[formIndex].val).format('YYYY-MM-DD HH:mm')
  }

  defineExpose({
    getCustomField: async (moduleId: string) => {
      await getCustomField(moduleId)
      forms.value = customFieldList.value.map((field, index) => {
        return {
          name: field.name,
          val: '',
          vals: [],
          repairFieldId: field.id,
          repairModuleFieldRelationId: field.repairModuleFieldRelationId,
          type: field.type,
          fileList: [],
          tip: field.tip,
          uploadQty: field.uploadQty,
          uploadSize: field.uploadSize,
          contentVos: field.contentVos,
          valIndex: index,
          required: field.required,
        }
      })
    },
    getForm: async () => {
      if (forms.value.length <= 0) {
        return null
      }

      if (!formInstance.value) {
        return null
      }

      try {
        await formInstance.value.validate()
        return forms.value
      } catch (error) {
        return []
      }
    },
  })
</script>

<template>
  <div v-if="forms.length > 0" v-loading="loading" class="new-return-factory-custom-info">
    <div class="title">自定义信息</div>
    <div class="divider"></div>
    <div class="form">
      <el-form ref="formInstance" inline-message :model="forms" label-position="top">
        <template
          v-for="(field, index) in forms.filter((item) => [1, 3, 4, 8, 9, 10].includes(item.type))"
          :key="index"
        >
          <el-form-item
            :label="field.name"
            :prop="[field.valIndex, field.type === 4 ? 'vals' : 'val']"
            :rules="[
              {
                required: field.required,
                message: field.tip || '内容不能为空',
                trigger: ['blur', 'change'],
              },
            ]"
          >
            <!-- 单行文本 -->
            <el-input
              v-if="field.type === 1"
              v-model.trim="forms[index].val"
              :placeholder="field.tip || '请输入内容'"
              maxlength="100"
            />

            <!-- 单选 -->
            <el-select
              v-if="field.type === 3"
              v-model="forms[field.valIndex].val"
              :placeholder="field.tip || '请选择'"
            >
              <el-option
                v-for="(option, optionIndex) in field.contentVos"
                :key="optionIndex"
                :label="option.val"
                :value="option.val"
              ></el-option>
            </el-select>

            <!-- 多选 -->
            <el-select
              v-if="field.type === 4"
              v-model="forms[field.valIndex].vals"
              :placeholder="field.tip || '请选择'"
              multiple
              collapse-tags
              collapse-tags-tooltip
              :max-collapse-tags="3"
            >
              <el-option
                v-for="(option, optionIndex) in field.contentVos"
                :key="optionIndex"
                :label="option.val"
                :value="option.val"
              ></el-option>
            </el-select>

            <!-- 评分 -->
            <el-rate
              v-if="field.type === 8"
              allow-half
              :model-value="Number(forms[field.valIndex].val) / 2 || 0"
              @change="(val: number) => forms[field.valIndex].val = String(val * 2)"
            ></el-rate>

            <!-- 日期 -->
            <el-date-picker
              v-if="field.type === 9"
              v-model="forms[field.valIndex].val"
              :placeholder="field.tip || '请选择日期'"
              @change="handleChangeDate(field.valIndex)"
            ></el-date-picker>

            <!-- 日期时间 -->
            <el-date-picker
              v-if="field.type === 10"
              v-model="forms[field.valIndex].val"
              type="datetime"
              format="YYYY-MM-DD HH:mm"
              date-format="MMM DD, YYYY"
              time-format="HH:mm"
              :placeholder="field.tip || '请选择日期时间'"
              @change="handleChangeDateTime(field.valIndex)"
            />
          </el-form-item>
        </template>

        <!-- 多行文本 -->
        <template v-for="(field, index) in forms.filter((item) => item.type === 2)" :key="index">
          <el-form-item
            :label="field.name"
            :prop="[field.valIndex, 'val']"
            :rules="[
              {
                required: field.required,
                message: field.tip || '内容不能为空',
                trigger: ['blur', 'change'],
              },
            ]"
          >
            <el-input
              v-model.trim="forms[field.valIndex].val"
              :placeholder="field.tip || '请输入'"
              type="textarea"
              maxlength="200"
              show-word-limit
              resize="both"
            />
          </el-form-item>
        </template>

        <template
          v-for="(field, index) in forms.filter((item) => [5, 6, 7].includes(item.type))"
          :key="index"
        >
          <el-form-item
            :label="`${field.name}（最多上传${field.uploadQty}${field.type === 5 ? '张' : '个'}）`"
            :prop="[field.valIndex, 'val']"
            :rules="[
              {
                validator: (rule, value, callback) => fileUploadValidator(callback, field.valIndex),
                trigger: ['blur', 'change'],
              },
            ]"
          >
            <!-- 图片上传 -->
            <div v-if="field.type === 5" class="file-list">
              <div
                v-for="(picture, pictureIndex) in forms[field.valIndex].fileList"
                :key="pictureIndex"
                class="file"
              >
                <h-image
                  :width="80"
                  :height="50"
                  :src="picture.url"
                  :padding="2"
                  :initial-index="index"
                  :preview-src-list="forms[field.valIndex].fileList.map((item) => item.url)"
                  @del="handleDelFile(field.valIndex, index)"
                ></h-image>

                <h-tooltip-text
                  :text="picture.file.name"
                  :max-width="80"
                  :height="16"
                ></h-tooltip-text>
              </div>
              <el-upload
                v-if="field.fileList.length < field.uploadQty"
                class="upload-picture upload-wrapper"
                multiple
                accept="image/*"
                :auto-upload="false"
                :on-change="(file: UploadFile) => handleCustomFieldUploadFile(file, field.valIndex)"
                :show-file-list="false"
                @click="pictureUploadFailInfoTipCount = 0"
              >
                <el-icon :size="24" color="#007cff">
                  <upload-filled />
                </el-icon>
              </el-upload>
            </div>

            <!-- 附件上传 -->
            <div v-if="field.type === 6" class="file-list">
              <div
                v-for="(file, fileIndex) in forms[field.valIndex].fileList"
                :key="fileIndex"
                class="file"
              >
                <h-image
                  :width="80"
                  :height="50"
                  :src="pdf"
                  :padding="2"
                  :is-show-img-preview="false"
                  @preview="handlePdfPreview(field.valIndex, index)"
                  @del="handleDelFile(field.valIndex, index)"
                ></h-image>

                <h-tooltip-text
                  :text="file.file.name"
                  :max-width="80"
                  :height="16"
                ></h-tooltip-text>
              </div>
              <el-upload
                v-if="field.fileList.length < field.uploadQty"
                class="upload-annex upload-wrapper"
                multiple
                accept=".pdf"
                :auto-upload="false"
                :on-change="(file: UploadFile) => handleCustomFieldUploadFile(file, field.valIndex)"
                :show-file-list="false"
                @click="pdfUploadFailInfoTipCount = 0"
              >
                <el-icon :size="24" color="#007cff">
                  <upload-filled />
                </el-icon>
              </el-upload>
            </div>

            <!-- 视频上传 -->
            <div v-if="field.type === 7" class="file-list">
              <div
                v-for="(file, fileIndex) in forms[field.valIndex].fileList"
                :key="fileIndex"
                class="file"
              >
                <h-image
                  :width="80"
                  :height="50"
                  :src="video"
                  :padding="2"
                  :is-show-img-preview="false"
                  @preview="handleVideoPreview(field.valIndex, index)"
                  @del="handleDelFile(field.valIndex, index)"
                ></h-image>

                <h-tooltip-text
                  :text="file.file.name"
                  :max-width="80"
                  :height="16"
                ></h-tooltip-text>
              </div>
              <el-upload
                v-if="field.fileList.length < field.uploadQty"
                class="upload-video upload-wrapper"
                multiple
                accept="video/*"
                :auto-upload="false"
                :on-change="(file: UploadFile) => handleCustomFieldUploadFile(file, field.valIndex)"
                :show-file-list="false"
                @click="videoUploadFailInfoTipCount = 0"
              >
                <el-icon :size="24" color="#007cff">
                  <upload-filled />
                </el-icon>
              </el-upload>
            </div>
          </el-form-item>
        </template>
      </el-form>
    </div>

    <pdf-preview
      v-model:visible="pdfPreviewDialogVisible"
      :pdf-list="pdfPreviewList"
      :initial-index="currentPdfPreviewIndex"
    ></pdf-preview>

    <video-preview
      v-model:visible="videoPreviewDialogVisible"
      :video-list="videoPreviewList"
      :initial-index="currentVideoPreviewIndex"
    ></video-preview>
  </div>
</template>

<style scoped lang="scss">
  :deep(.el-form-item) {
    margin: 0;
  }

  .new-return-factory-custom-info {
    display: flex;
    flex-direction: column;

    .title {
      padding-left: 6px;
      border-left: 3px solid $primaryColor;
      font-size: 14px;
      font-weight: bold;
    }

    .divider {
      margin: 10px 0;
      border-bottom: 1px dotted #e5e5e5;
    }

    .form {
      :deep(.el-form) {
        display: grid;
        grid-template-columns: repeat(auto-fill, 440px);
        column-gap: 100px;
        margin-top: 18px;
        row-gap: 18px;
        padding: 0 38px;

        .el-form-item {
          width: 100%;
          .el-form-item__label {
            height: 16px;
            line-height: 16px;
            margin: 0 0 3px 0;
          }

          .el-form-item__content {
            width: 100%;
            flex-direction: column;
            align-items: flex-start;

            .el-form-item__error {
              padding: 0;
              margin: 3px 0 0 0;
            }

            .el-date-editor {
              width: 100%;
              height: 28px;

              .el-input__wrapper {
                height: 26px;
              }
            }

            .el-rate {
              height: 28px;
            }

            .file-list {
              margin-top: 5px;
              display: flex;
              gap: 5px;
              flex-wrap: wrap;

              .upload-wrapper {
                width: 80px;
                height: 50px;
                box-shadow: 0 0 0 1px #dcdfe6 inset;

                .el-upload {
                  width: 100%;
                  height: 100%;
                  display: flex;
                  justify-content: center;
                  flex-direction: column;

                  .text {
                    line-height: 16px;
                    height: 16px;
                    color: #999;
                  }
                }
              }
            }

            .el-textarea {
              width: 100%;

              .el-textarea__inner {
                width: 100% !important;
                min-height: 28px !important;
                height: 28px;
                max-height: 140px !important;
              }
            }
          }
        }
      }
    }
  }
</style>
